package com.acwing.partition13;

import java.io.*;

/**
 * @author `RKC`
 * @date 2022/3/7 10:17
 */
public class AC1217垒骰子_dp {

    private static final int MOD = 1000000007;
    private static int[] dict = {0, 4, 5, 6, 1, 2, 3};
    //conf[i][j]表示面i和面j是否冲突
    private static boolean[][] conf = new boolean[7][7];
    //f[i][j]表示高度为i，且最高层面朝上的数字是j的合法方案数
    private static long[][] f;
    private static int n, m;

    private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        String[] ss = reader.readLine().split(" ");
        n = Integer.parseInt(ss[0]);
        m = Integer.parseInt(ss[1]);
        f = new long[n + 1][7];
        for (int i = 0; i < m; i++) {
            ss = reader.readLine().split(" ");
            int a = Integer.parseInt(ss[0]), b = Integer.parseInt(ss[1]);
            conf[a][b] = conf[b][a] = true;
        }
        //对于第一层的骰子来说，可以选择任意面朝上
        for (int i = 1; i <= 6; i++) f[1][i] = 4;
        //从第二层遍历每一层，枚举当前层的朝上的面j和下一层朝上的面k，如果不发生冲突就进行状态转移
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= 6; j++) {
                for (int k = 1; k <= 6; k++) {
                    //只有不冲突才能加上下面层的方案数
                    if (!conf[dict[j]][k]) {
                        f[i][j] = (f[i][j] + 4 * f[i - 1][k] % MOD) % MOD;
                    }
                }
            }
        }
        long ans = 0;
        for (int i = 1; i <= 6; i++) ans = (ans + f[n][i]) % MOD;
        writer.write(ans + "\n");
        writer.flush();
    }
}
